package cn.sys.service.impl;

import cn.sys.controller.dto.DormitoryInfoDTO;
import cn.sys.controller.dto.SearchDTO;
import cn.sys.dao.DormitoryDao;
import cn.sys.dao.DormitoryPositionDao;
import cn.sys.dao.StudentDao;
import cn.sys.entity.Dormitory;
import cn.sys.entity.DormitoryPosition;
import cn.sys.entity.Student;
import cn.sys.service.DormitoryService;
import cn.sys.util.MybatisUtil;
import cn.sys.util.ResultData;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.ibatis.session.SqlSession;

import java.util.*;

public class DormitoryServiceImpl implements DormitoryService {
    private SqlSession sqlSession = MybatisUtil.getSQLSession();

    /**
     * 根据用户id查询到宿舍信息，并将其封装到DormitoryInfoDTO中返回给controller层
     * @param stuId 用户id
     * @return
     */
    @Override
    public ResultData findDormitoryInfoByStuId(Integer stuId) {
        DormitoryDao dormitoryDao = sqlSession.getMapper(DormitoryDao.class);
        DormitoryInfoDTO dormitoryInfoDTO = dormitoryDao.findDormitoryByStuId(stuId);
        if(dormitoryInfoDTO == null){
            return ResultData.fail(ResultData.DORMITORY_INFO_EMPTY, "当前没有宿舍信息");
        }
        // 信息处理
        String type = dormitoryInfoDTO.getType();
        switch (type){
            case "2":
                dormitoryInfoDTO.setType("二人间");
                break;
            case "4":
                dormitoryInfoDTO.setType("四人间");
                break;
            case "6":
                dormitoryInfoDTO.setType("六人间");
                break;
            default:
                break;
        }
        String state = dormitoryInfoDTO.getState();
        switch (state){
            case "0":
                dormitoryInfoDTO.setState("空寝");
                break;
            case "1":
                dormitoryInfoDTO.setState("男寝");
                break;
            case "2":
                dormitoryInfoDTO.setState("女寝");
                break;
            default:
                break;
        }

        int num = dormitoryDao.findDormitoryCountByDorId(dormitoryInfoDTO.getDorId());
        dormitoryInfoDTO.setNum(num);
        ResultData resultData = new ResultData(ResultData.DORMITORY_INFO_NOT_EMPTY, "查询成功", dormitoryInfoDTO);
        return resultData;
    }

    /**
     * 宿舍信息统计
     * 宿舍总间数，宿舍总床位数，已入住人数，已入住男生人数，已入住女生人数，
     * 男寝剩余床位数、女寝剩余床位数、空寝室总数目，
     * 双人间空寝室数、四人间空寝室数、六人间空寝室数
     * @return
     */
    @Override
    public ResultData statisticDormitoryInfo() {
        DormitoryDao dormitoryDao = sqlSession.getMapper(DormitoryDao.class);
        Map<String, Object> dormitoryStatistical = new HashMap<>();
        // 1. 宿舍中间数、宿舍中床位数
        List<Map<String, Object>> list = dormitoryDao.findDormitoryTotal();
        dormitoryStatistical.put("bedTotal", list.get(0).get("bedTotal"));
        dormitoryStatistical.put("doorTotal", list.get(0).get("doorTotal"));
        // 2. 已入住人数
        Integer livingCount = dormitoryDao.findDormitoryLivingCount();
        dormitoryStatistical.put("livingCount", livingCount);
        // 3. 已入住男、女人数
        Integer livingBoyCount = dormitoryDao.findDormitoryGenderCount(1);
        Integer livingGirlCount = dormitoryDao.findDormitoryGenderCount(2);
        dormitoryStatistical.put("livingBoyCount", livingBoyCount);
        dormitoryStatistical.put("livingGirlCount", livingGirlCount);
        // 4. 剩余床位数
        Integer totalBedBoyCount = dormitoryDao.findDormitoryBedGenderCount(1);
        Integer totalBedGirlCount = dormitoryDao.findDormitoryBedGenderCount(2);
        dormitoryStatistical.put("remainBedBoyCount", totalBedBoyCount - livingBoyCount);
        dormitoryStatistical.put("remainBedGirlCount", totalBedGirlCount - livingGirlCount);
        // 空寝室总数目
        Integer emptyDormitoryCount = dormitoryDao.findEmptyDormitoryCount();
        dormitoryStatistical.put("emptyDormitoryCount", emptyDormitoryCount);
        // 2\4\6人间空寝数
        Integer emptyTwoCount = dormitoryDao.findDormitoryTypeCount(2);
        Integer emptyFourCount = dormitoryDao.findDormitoryTypeCount(4);
        Integer emptySixCount = dormitoryDao.findDormitoryTypeCount(6);
        dormitoryStatistical.put("emptyTwoCount",emptyTwoCount);
        dormitoryStatistical.put("emptyFourCount",emptyFourCount);
        dormitoryStatistical.put("emptySixCount",emptySixCount);
        ResultData resultData = new ResultData();
        resultData.put("code", ResultData.OPERATION_SUCCESS);
        resultData.put("dormitoryStatistical", dormitoryStatistical);
        return resultData;
    }

    /**
     * 宿舍信息及位置查询，封装到map中返回
     * @return
     */
    @Override
    public ResultData findAllDormitoryPostion() {
        DormitoryDao dormitoryDao = sqlSession.getMapper(DormitoryDao.class);
        DormitoryPositionDao dormitoryPositionDao = sqlSession.getMapper(DormitoryPositionDao.class);
        List<DormitoryPosition> dormitoryPositions = dormitoryPositionDao.findAllDormitoryPosition();
        ResultData resultData = new ResultData();
        resultData.put("dormitoryPositions", dormitoryPositions);

        return resultData;
    }

    @Override
    public ResultData findDormitoryChooseable(SearchDTO searchDTO) {
        StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
        DormitoryDao dormitoryDao = sqlSession.getMapper(DormitoryDao.class);
        // 先从学生表查询是否存在学生信息，如果存在返回其性别信息
        Integer stuId = searchDTO.getStuId();
        Student student = studentDao.findStudentById(stuId);
        if(student == null){
            return ResultData.fail(ResultData.OPERATION_FAIL, "学生信息不存在");
        }

        // 查询学生是否已经加入了某寝室
        Integer dorId =  dormitoryDao.findStuDormitoryByStuId(stuId);
        if(dorId != null){
            return ResultData.fail(ResultData.OPERATION_FAIL, "当前学生已有入住的寝室");
        }

        // 得到学生性别，决定查询的寝室状态
        int state = (student.getGender().equals("男")?1:2);

        // 分页操作
        PageHelper.startPage(searchDTO.getPageNum(), searchDTO.getPageSize());
        List<Dormitory> allDormitories = dormitoryDao.findAllDormitoryChooseable(state, searchDTO.getDorPosId());
        // 判断宿舍 是否已经满员
        List<Dormitory> dormitories = new ArrayList<>();
        for (Dormitory dormitory : allDormitories){
            // 如果没有满员，重新放入dormitories中
            int count = dormitoryDao.findDormitoryCountByDorId(dormitory.getDorId());
            if(count < dormitory.getMaxNum()){
                dormitories.add(dormitory);
            }
        }
        // 分页信息
        PageInfo<Dormitory> pageInfo = PageInfo.of(dormitories);
        ResultData resultData = new ResultData();
        resultData.put("result", true);
        resultData.put("msg", "");
        Map<String, Object> pageMap = new HashMap<>();
        pageMap.put("currPage", searchDTO.getPageNum());
        pageMap.put("total", pageInfo.getTotal());
        pageMap.put("pageSize", searchDTO.getPageSize());
        resultData.put("pagination", pageMap);
        resultData.put("datas", dormitories);

        return resultData;
    }

    /**
     * 添加学生到寝室，如果寝室为空寝，则还需要修改寝室的状态
     * @param dorId 寝室id
     * @param stuId 学生id
     * @Param state 宿舍的状态
     * @return
     */
    @Override
    public ResultData addStuToDormitory(Integer dorId, Integer stuId, Integer state) {
        DormitoryDao dormitoryDao = sqlSession.getMapper(DormitoryDao.class);
        StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
        Date createTime = new Date();
        int i = dormitoryDao.addStuDormitory(dorId, stuId, 0, createTime);
        if(i>0) {
            if (state == 0) {
                // 根据学生id查询学生性别
                Student student = studentDao.findStudentById(stuId);
                if("男".equals(student.getGender())){
                    dormitoryDao.updateDormitoryState(dorId, 1);
                }else {
                    dormitoryDao.updateDormitoryState(dorId, 2);
                }
            }
            // 添加成功，剩余床位数减一
            int z = dormitoryDao.updateDormitorySurplusNum(dorId, -1);

            return ResultData.ok(ResultData.OPERATION_SUCCESS, "操作成功");
        }

        return ResultData.fail(ResultData.OPERATION_FAIL, "操作失败，请稍后再试");
    }

    /**
     * 添加宿舍信息
     * @param dormitory
     * @return
     */
    @Override
    public ResultData addDormitory(Dormitory dormitory) {
        DormitoryDao dormitoryDao = sqlSession.getMapper(DormitoryDao.class);
        int i = dormitoryDao.addDormitory(dormitory);
        if(i>0){
            return ResultData.ok(ResultData.OPERATION_SUCCESS, "添加成功");
        }
        return ResultData.fail(ResultData.OPERATION_FAIL, "添加失败，请稍后再试");
    }

    /**
     * 查询宿舍信息以及其位置信息，将信息拼接后封装
     * @return
     */
    @Override
    public ResultData findDormitoryAndPostions() {
        DormitoryDao dormitoryDao = sqlSession.getMapper(DormitoryDao.class);
        List<Map<String, Object>> list = dormitoryDao.findDormitoryAndPositions();
        List<Map<String, Object>> dorIdAndPosition = new ArrayList<>();
        for(Map<String, Object> info : list){
            Map<String, Object> map = new HashMap<>();
            map.put("dorId", info.get("dor_id"));
            map.put("position", (String)info.get("apartment_name") + info.get("floor") + "栋" + info.get("door_num"));
            dorIdAndPosition.add(map);
        }
        ResultData resultData = new ResultData();
        resultData.put("dorIdAndPosition", dorIdAndPosition);
        return resultData;
    }

    /**
     * 根据宿舍id查询宿舍信息
     * @param dorId
     * @return
     */
    @Override
    public ResultData findDormitoryByDorId(Integer dorId) {
        DormitoryDao dormitoryDao = sqlSession.getMapper(DormitoryDao.class);
        Dormitory dormitory = dormitoryDao.findDormitoryByDorId(dorId);
        if(dormitory != null){
            return new ResultData(ResultData.OPERATION_SUCCESS, "查询成功", dormitory);
        }
        return ResultData.fail(ResultData.OPERATION_FAIL, "没有查到宿舍信息");
    }

    /**
     * 修改宿舍信息，除前端传来的数据外，还需要添加修改时间、修改剩余床位数、管理员id（controller中已添加）
     * @param dormitory
     * @return
     */
    @Override
    public ResultData updateDormitoryInfo(Dormitory dormitory) {
        DormitoryDao dormitoryDao = sqlSession.getMapper(DormitoryDao.class);
        Dormitory oldInfo =  dormitoryDao.findDormitoryByDorId(dormitory.getDorId());
        // 修改时间
        Date updateTime = new Date();
        dormitory.setUpdateTime(updateTime);
        // 剩余床位数，如果剩余床位数小于0，则不修改（现在的最大住宿人数-原来的最大住宿人数+剩余床位数）
        int surplusNum = dormitory.getMaxNum() - oldInfo.getMaxNum() + oldInfo.getSurplusNum();
        dormitory.setSurplusNum(surplusNum);
        if(surplusNum < 0){
            return ResultData.fail(ResultData.OPERATION_FAIL, "修改后的最大住宿人数小于当前住宿人数，不能修改");
        }
        int i = dormitoryDao.updateDormitoryInfo(dormitory);
        if(i>0){
            return ResultData.ok(ResultData.OPERATION_SUCCESS, "修改成功");
        }
        return ResultData.fail(ResultData.OPERATION_FAIL, "操作失败，请稍后再试");
    }

    // 查询所有的宿舍信息

    @Override
    public ResultData findAllDormitoryAndPosition() {
        DormitoryDao dormitoryDao = sqlSession.getMapper(DormitoryDao.class);
        DormitoryPositionDao dormitoryPositionDao = sqlSession.getMapper(DormitoryPositionDao.class);
        List<DormitoryPosition> dormitoryPositions = dormitoryPositionDao.findAllDormitoryPosition();
        List<Dormitory> dormitories = dormitoryDao.findAllDormitory();
        ResultData resultData = new ResultData();
        resultData.put("dormitoryPositions", dormitoryPositions);
        resultData.put("dormitories",dormitories);
        return resultData;
    }

    /**
     * 根据条件查询寝室列表
     * @param searchDTO
     * @return
     */
    @Override
    public ResultData findDormitoryListBySearch(SearchDTO searchDTO) {
        DormitoryDao dormitoryDao = sqlSession.getMapper(DormitoryDao.class);
        PageHelper.startPage(searchDTO.getPageNum(), searchDTO.getPageSize(), searchDTO.getOrderBy());
        List<Dormitory> dormitories = dormitoryDao.findDormitoryListBySearch(searchDTO);
        PageInfo pageInfo = PageInfo.of(dormitories);
        ResultData resultData = new ResultData();
        resultData.put("result", true);
        resultData.put("msg", "");
        Map<String, Object> pageMap = new HashMap<>();
        pageMap.put("currPage", searchDTO.getPageNum());
        pageMap.put("total", pageInfo.getTotal());
        pageMap.put("pageSize", searchDTO.getPageSize());
        resultData.put("pagination", pageMap);
        resultData.put("datas", dormitories);
        return resultData;
    }

    /**
     * 根据寝室id查询学生列表和寝室信息
     * @return
     */
    @Override
    public ResultData findDormitoryAndStudentListByDorId(SearchDTO searchDTO) {
        DormitoryDao dormitoryDao = sqlSession.getMapper(DormitoryDao.class);
        StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
        DormitoryPositionDao dormitoryPositionDao = sqlSession.getMapper(DormitoryPositionDao.class);
        Dormitory dormitory = dormitoryDao.findDormitoryByDorId(searchDTO.getDorId());
        DormitoryPosition dormitoryPosition = dormitoryPositionDao.findDormitoryPositionByDorPosId(dormitory.getDorPosId());
        List<Map<String, Object>> stuDormitories = studentDao.findStuDormitoryByDorId(searchDTO.getDorId());

        PageHelper.startPage(searchDTO.getPageNum(), searchDTO.getPageSize());
        PageInfo pageInfo = PageInfo.of(stuDormitories);
        ResultData resultData = new ResultData();
        resultData.put("result", true);
        resultData.put("msg", "");
        Map<String, Object> pageMap = new HashMap<>();
        pageMap.put("currPage", searchDTO.getPageNum());
        pageMap.put("total", pageInfo.getTotal());
        pageMap.put("pageSize", searchDTO.getPageSize());
        resultData.put("pagination", pageMap);
        resultData.put("datas", stuDormitories);
        resultData.put("dormitory",dormitory);
        resultData.put("dormitoryPosition", dormitoryPosition);
        return resultData;
    }
}
